Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make collection iterators forward_iterator* and beyond #720

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

m-fila
Copy link
Contributor

@m-fila m-fila commented Dec 20, 2024

BEGINRELEASENOTES

  • Collection iterators fulfill forward_iterator, bidirectional_iterator and random_access_iteratorconcepts. The collections can be used with more categories of range algorithms - up to random_access_range, for example std::adjacent_find, std::lower_bound, std::fold_right, and more views like std::ranges::views::reverse

ENDRELEASENOTES

Here is a proposal how to make collection iterators fulfill std::forward_iterator which also opens the way for std::bidirectional_iterator and std::random_access_iterator by making a single exception

The collection iterators fulfill all the forward_iterator requirements except one semantic requirement:

Pointers and references obtained from a forward iterator into a range remain valid while the range exists.

The problem here is the operator-> that returns a pointer to data type object that is a member of the iterator (collections store data layer objects and data type are created on-the-fly so there is no data type object with lifetime livinf inside collection to which pointer we could return). Due to this the validity of obtained pointer is as long as the iterator is valid - to fulfill the requirement it should be as long the collection is valid.

In reality it's quite hard to abuse as things obtained through -> (iterator->energy()) are safe since they go through the data layer that lives in the collection. The problem seems to be only getting the pointer directly with pattern like this:

auto* ptr = iterator.operator->();

which is rather rare in normal usage. A pattern like this auto particle = *(iterator.operator->()); again is okay since the pointer is used immediately

Of course the final question is whether it's used somewhere in an implementation of the std algorithms. On top of that it should be used in a certain way like creating a temporary copy of iterator, taking pointer, disposing of the copy, using iterator

In the past there were some precedence event in the standard library that iterators were assigned some category except something (that was for Legacy iterators):

TL;DR Iterators gain support up to std::random_access_iterator except that technically they don't meet a requirement for pointers obtained with auto* ptr = it.operator->(); pattern to outlive the iterator

@m-fila
Copy link
Contributor Author

m-fila commented Dec 20, 2024

Ah used <=> to define comparison operators. I think I'll leave it with that since the move to C++20 is upcoming anyway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant